/*
 * Copyright (c) 2024, Qi Yaolong.
 * dragon@hbu.edu.cn
 * HeBei University, China.
 * 
 * 简体中文
 * 保留所有权利。除非符合（遵守）以下条款，否则您不得使用此文件：
 * 
 * 禁止任何未经授权的个人或组织以任何形式将本程序及其附属资料、创新、创意、架构设计、算法、衍生作品
 * 等用于任何商业目的、盈利活动、各类竞赛(比赛)、直播教学、录播教学、线下课程、书籍编写、教材编写、
 * 会议、培训、公益活动、项目课题、毕业设计、毕业论文、学术论文等。
 * 
 * 本程序由版权持有人和贡献人“按原样”提供，不提供任何明示或暗示担保，包括但不局限于对适销性和特定
 * 用途适合性的暗示担保。在任何情况下，版权持有人或贡献人对因使用本程序而导致的任何直接、间接、附带、
 * 特殊、典型或后果性损害（包括但不限于购买替代商品或服务；使用损失、数据丢失或利润损失；业务中断）
 * 不承担任何责任，无论其如何产生，也不论其责任理论为何，无论是合同、严格责任还是侵权（包括疏忽或
 * 其他），即使已告知此类损害的可能性。
 * 
 * English
 * All rights reserved. You may NOT use this file except in compliance with the
 * following terms:
 * 
 * IT IS PROHIBITED FOR ANY UNAUTHORIZED PERSON OR ENTITY TO USE THIS PROGRAM AND 
 * ITS ANCILLARY DATA, INNOVATIONS, CONCEPTS, ARCHITECTURE DESIGN, ALGORITHMS, 
 * DERIVED WORKS, ETC., IN ANY FORM FOR COMMERCIAL PURPOSES, PROFIT-MAKING 
 * ACTIVITIES, VARIOUS COMPETITIONS (CONTESTS), LIVE TEACHING, PRE-RECORDED 
 * LESSONS, OFFLINE COURSES, BOOK WRITING, CONFERENCES, TRAININGS, PUBLIC WELFARE 
 * ACTIVITIES, PROJECTS, TOPICS, GRADUATION DESIGNS, DISSERTATIONS, THESES, AND 
 * OTHER APPLICATIONS.
 * 
 * THIS PROGRAM IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS PROGRAM, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "cmsis_os2.h"
#include "ohos_init.h"
#include "securec.h"
#include "sle_common.h"
#include "osal_debug.h"
#include "sle_errcode.h"
#include "osal_addr.h"
#include "osal_task.h"
#include "sle_connection_manager.h"
#include "sle_device_discovery.h"
#include "ohos_sle_common.h"
#include "ohos_sle_errcode.h"
#include "ohos_sle_ssap_server.h"
#include "ohos_sle_ssap_client.h"
#include "ohos_sle_device_discovery.h"
#include "ohos_sle_connection_manager.h"
#include "pinctrl.h"
#include "errcode.h"
#include "../inc/sle_server_adv.h"
#include "../inc/sle_server.h"

#include "iot_gpio.h"   
#include "iot_gpio_ex.h"

#define OCTET_BIT_LEN 8 
#define UUID_LEN_2 2   
#define UUID_INDEX 14   

#define COUNT 10 
#define SG92R_TASK_STACK_SIZE 0x1000
#define SG92R_TASK_PRIO 17
#define BSP_SG92R 2
#define FREQ_TIME 20000

#define BUTTON_GPIO 1 
#define BUTTON_GPIO2 14 


#define SLE_ADV_HANDLE_DEFAULT 1


static char g_sle_uuid_app_uuid[UUID_LEN_2] = {0x12, 0x34};


static char g_sle_property_value[OCTET_BIT_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};


static uint16_t g_sle_conn_id = 0;


static uint8_t g_server_id = 0;

static uint16_t g_service_handle = 0;


static uint16_t g_property_handle = 0;


SleAcbStateType g_sle_conn_state = OH_SLE_ACB_STATE_NONE;


SlePairStateType g_sle_pair_state = OH_SLE_PAIR_NONE;


#define UUID_16BIT_LEN 2


#define UUID_128BIT_LEN 16


#define SLE_SERVER_LOG "[sle server]"


static uint8_t g_sle_base[] = {0x37, 0xBE, 0xA8, 0x80, 0xFC, 0x70, 0x11, 0xEA,
                               0xB7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


static void encode2byte_little(uint8_t *_ptr, uint16_t data)
{
    *(uint8_t *)((_ptr) + 1) = (uint8_t)((data) >> 0x8);
    *(uint8_t *)(_ptr) = (uint8_t)(data);
}


static volatile int g_ledState = 0;
static volatile int g_ledState2 = 0;

static void OnButtonPressed1(char *arg)
{
    (void)arg;
    g_ledState =!g_ledState;
   
}

static void OnButtonPressed2(char *arg)
{
    (void)arg;
    g_ledState2 =!g_ledState2;
    
}

void SetAngle(unsigned int duty)
{
    unsigned int time = FREQ_TIME;

    IoTGpioSetDir(BUTTON_GPIO, IOT_GPIO_DIR_IN);     

    IoSetPull(BUTTON_GPIO, IOT_IO_PULL_UP);

    IoTGpioSetDir(BUTTON_GPIO2, IOT_GPIO_DIR_IN);     
   
    IoSetPull(BUTTON_GPIO2, IOT_IO_PULL_UP);

    IoTGpioSetDir(BSP_SG92R, IOT_GPIO_DIR_OUT);      
    uapi_systick_delay_us(duty);                     
    IoTGpioSetOutputVal(BSP_SG92R, IOT_GPIO_VALUE1); 

    uapi_systick_delay_us(time - duty);
}

void RegressMiddle(void)
{
    unsigned int angle = 1500;
    for (int i = 0; i < COUNT; i++) {
        SetAngle(angle);
    }
}

void EngineTurnRight(void)
{
       errcode_t ret2 = IoTGpioRegisterIsrFunc(BUTTON_GPIO2, 
                                           IOT_INT_TYPE_EDGE, 
                                           IOT_GPIO_EDGE_FALL_LEVEL_LOW, 
                                           OnButtonPressed2, 
                                           NULL);
    if (ret2!= 0) {
       
        return;
    }
    while (1) {
       
        if (g_ledState2) {
           
            for (int i = 0; i < COUNT; i++) {
                SetAngle(2500);
            }
           
        } else {
           
            RegressMiddle();
        }
        osDelay(10);  
    }
}

void EngineTurnLeft(void)
{
    
    errcode_t ret = IoTGpioRegisterIsrFunc(BUTTON_GPIO, 
                                          IOT_INT_TYPE_EDGE, 
                                          IOT_GPIO_EDGE_FALL_LEVEL_LOW, 
                                          OnButtonPressed1, 
                                          NULL);
    if (ret!= 0) {
        return;
    }
    while (1) {
        if (g_ledState) {
          
            RegressMiddle();
            
            printf("Button pressed.\r\n");
        } else {
           
            for (int i = 0; i < COUNT; i++) {
                SetAngle(500);
            }
        }
        osDelay(10);  
    }
}

static void sle_uuid_set_base(SleUuid *out)
{
    errcode_t ret;
    
    ret = memcpy_s(out->uuid, SLE_UUID_LEN, g_sle_base, SLE_UUID_LEN); 
    if (ret!= EOK)
    {
       
        printf("%s [sle_uuid_set_base] memcpy fail\n", SLE_SERVER_LOG);
        out->len = 0;
        return;
    }
    out->len = UUID_LEN_2;
}

static void sle_uuid_setu2(uint16_t u2, SleUuid *out)
{
   
    sle_uuid_set_base(out);
    out->len = UUID_LEN_2;
   
    encode2byte_little(&out->uuid[UUID_INDEX], u2);
}


static void sle_uuid_print(SleUuid *uuid)
{
    if (uuid == NULL)
    {
       
        printf("%s uuid_print,uuid is null\r\n", SLE_SERVER_LOG);
        return;
    }
    if (uuid->len == UUID_16BIT_LEN)
    {
       
        printf("%s uuid: %02x %02x.\n", SLE_SERVER_LOG,
                            uuid->uuid[14], uuid->uuid[15]); 
    }
    else if (uuid->len == UUID_128BIT_LEN)
    {
       
        printf("%s uuid: \n", SLE_SERVER_LOG); 
        printf("%s 0x%02x 0x%02x 0x%02x \n", SLE_SERVER_LOG, uuid->uuid[0], uuid->uuid[1],
                            uuid->uuid[2], uuid->uuid[3]);
        printf("%s 0x%02x 0x%02x 0x%02x \n", SLE_SERVER_LOG, uuid->uuid[4], uuid->uuid[5],
                            uuid->uuid[6], uuid->uuid[7]);
        printf("%s 0x%02x 0x%02x 0x%02x \n", SLE_SERVER_LOG, uuid->uuid[8], uuid->uuid[9],
                            uuid->uuid[10], uuid->uuid[11]);
        printf("%s 0x%02x 0x%02x 0x%02x \n", SLE_SERVER_LOG, uuid->uuid[12], uuid->uuid[13],
                            uuid->uuid[14], uuid->uuid[15]);
    }
}

static void ssaps_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id, SsapcExchangeInfo *mtu_size,
                                  errcode_t status)
{
    
    printf("%s [ssaps_mtu_changed_cbk] server_id:%x, conn_id:%x, mtu_size:%x, status:%x\r\n",
                        SLE_SERVER_LOG, server_id, conn_id, mtu_size->mtuSize, status);
}

static void ssaps_start_service_cbk(uint8_t server_id, uint16_t handle, errcode_t status)
{
    
    printf("%s [ssaps_start_service_cbk] server_id:%d, handle:%x, status:%x\r\n", SLE_SERVER_LOG,
                        server_id, handle, status);
}

static void ssaps_add_service_cbk(uint8_t server_id, SleUuid *uuid, uint16_t handle, errcode_t status)
{
   
    printf("%s [ssaps_add_service_cbk] server_id:%x, handle:%x, status:%x\r\n", SLE_SERVER_LOG,
                        server_id, handle, status);
   
    sle_uuid_print(uuid);
}


static void ssaps_add_property_cbk(uint8_t server_id, SleUuid *uuid, uint16_t service_handle,
                                   uint16_t handle, errcode_t status)
{
    
    printf("%s [ssaps_add_property_cbk] server_id:%x, service_handle:%x,handle:%x, status:%x\r\n",
                        SLE_SERVER_LOG, server_id, service_handle, handle, status);
   
    sle_uuid_print(uuid);
}

static void ssaps_add_descriptor_cbk(uint8_t server_id, SleUuid *uuid, uint16_t service_handle,
                                     uint16_t property_handle, errcode_t status)
{
    
    printf("%s [ssaps_add_descriptor_cbk] server_id:%x, service_handle:%x, property_handle:%x, \
        status:%x\r\n",
                        SLE_SERVER_LOG, server_id, service_handle, property_handle, status);
    
    sle_uuid_print(uuid);
}

static void ssaps_delete_all_service_cbk(uint8_t server_id, errcode_t status)
{
   
    printf("%s [ssaps_delete_all_service_cbk] server_id:%x, status:%x\r\n", SLE_SERVER_LOG,
                        server_id, status);
}

static errcode_t sle_ssaps_register_cbks(SsapsReadRequestCallback ssaps_read_request_cbk,
                                         SsapsWriteRequestCallback ssaps_write_request_cbk)
{
    errcode_t ret;
    SsapsCallbacks ssaps_cbk = {0};
   
    ssaps_cbk.addServiceCb = ssaps_add_service_cbk;             
   
    ssaps_cbk.addPropertyCb = ssaps_add_property_cbk;           
   
    ssaps_cbk.addDescriptorCb = ssaps_add_descriptor_cbk;       
  
    ssaps_cbk.startServiceCb = ssaps_start_service_cbk;         
    
    ssaps_cbk.deleteAllServiceCb = ssaps_delete_all_service_cbk; 
   
    ssaps_cbk.mtuChangedCb = ssaps_mtu_changed_cbk;             
    
    ssaps_cbk.readRequestCb = ssaps_read_request_cbk;           
    
    ssaps_cbk.writeRequestCb = ssaps_write_request_cbk;         

   
    ret = SsapsRegisterCallbacks(&ssaps_cbk);                   
    if (ret!= ERRCODE_SLE_SUCCESS)
    {
   
        printf("%s [sle_ssaps_register_cbks] ssaps_register_callbacks fail :%x\r\n", SLE_SERVER_LOG,
                            ret);
        return ret;
    }
    return ERRCODE_SLE_SUCCESS;
}

static errcode_t sle_uuid_server_service_add(void)
{
    errcode_t ret;
    SleUuid service_uuid = {0};

   
    sle_uuid_setu2(SLE_UUID_SERVER_SERVICE, &service_uuid);

   
    ret = SsapsAddServiceSync(g_server_id, &service_uuid, 1, &g_service_handle);
    if (ret!= ERRCODE_SLE_SUCCESS)
    {
        
        printf("%s sle uuid add service fail, ret:%x\r\n", SLE_SERVER_LOG, ret);
        return ERRCODE_SLE_FAIL;
    }

    return ERRCODE_SLE_SUCCESS;
}

static errcode_t sle_uuid_server_property_add(void)
{
    errcode_t ret;
    SsapsPropertyInfo property = {0}; 
    SsapsDescInfo descriptor = {0};   
    uint8_t ntf_value[] = {0x01, 0x02};

    
    property.permissions = SLE_UUID_TEST_PROPERTIES;

    
    property.operateIndication = SLE_UUID_TEST_OPERATION_INDICATION;

   
    sle_uuid_setu2(SLE_UUID_SERVER_NTF_REPORT, &property.uuid);

   
    property.valueLen = OCTET_BIT_LEN;

   
    property.value = (uint8_t *)osal_vmalloc(sizeof(g_sle_property_value));
    if (property.value == NULL)
    {
        return ERRCODE_SLE_FAIL;
    }
    
    if (memcpy_s(property.value, sizeof(g_sle_property_value), g_sle_property_value,
                 sizeof(g_sle_property_value))!= EOK)
    {
        osal_vfree(property.value);
        return ERRCODE_SLE_FAIL;
    }

 
    ret = SsapsAddPropertySync(g_server_id, g_service_handle, &property, &g_property_handle);
    if (ret!= ERRCODE_SLE_SUCCESS)
    {
        printf("%s sle add property fail, ret:%x\r\n", SLE_SERVER_LOG, ret);
        osal_vfree(property.value);
        return ERRCODE_SLE_FAIL;
    }

    
    descriptor.permissions = SLE_UUID_TEST_DESCRIPTOR;

   
    descriptor.type = SSAP_DESCRIPTOR_CLIENT_CONFIGURATION;

   
    descriptor.operateIndication = SLE_UUID_TEST_OPERATION_INDICATION;

    
    descriptor.value = (uint8_t *)osal_vmalloc(sizeof(ntf_value));
    if (descriptor.value == NULL)
    {
        osal_vfree(property.value);
        return ERRCODE_SLE_FAIL;
    }
    
    if (memcpy_s(descriptor.value, sizeof(ntf_value), ntf_value, sizeof(ntf_value))!= EOK)
    {
        osal_vfree(property.value);
        osal_vfree(descriptor.value);
        return ERRCODE_SLE_FAIL;
    }

   
    ret = SsapsAddDescriptorSync(g_server_id, g_service_handle, g_property_handle, &descriptor);
    if (ret!= ERRCODE_SLE_SUCCESS)
    {
        printf("%s sle add descriptor fail, ret:%x\r\n", SLE_SERVER_LOG, ret);
        osal_vfree(property.value);
        osal_vfree(descriptor.value);
        return ERRCODE_SLE_FAIL;
    }

    osal_vfree(property.value);
    osal_vfree(descriptor.value);
    return ERRCODE_SLE_SUCCESS;
}

static errcode_t sle_server_add(void)
{
    errcode_t ret;
    sle_uuid_t app_uuid = {0}; 

    
    printf("%s sle add service in\r\n", SLE_SERVER_LOG);
    app_uuid.len = sizeof(g_sle_uuid_app_uuid);
   
    if (memcpy_s(app_uuid.uuid, app_uuid.len, g_sle_uuid_app_uuid, sizeof(g_sle_uuid_app_uuid))!= EOK)
    {
        return ERRCODE_SLE_FAIL;
    }
  
    ssapsRegisterServer(&app_uuid, &g_server_id); 

   
    if (sle_uuid_server_service_add()!= ERRCODE_SLE_SUCCESS)
    {
        SsapsUnregisterServer(g_server_id); 
        return ERRCODE_SLE_FAIL;
    }

    if (sle_uuid_server_property_add()!= ERRCODE_SLE_SUCCESS)
    {
        SsapsUnregisterServer(g_server_id); 
        return ERRCODE_SLE_FAIL;
    }
    
    printf("%s sle add service, server_id:%x, service_handle:%x, property_handle:%x\r\n",
                        SLE_SERVER_LOG, g_server_id, g_service_handle, g_property_handle);

   
    ret = SsapsStartService(g_server_id, g_service_handle);
    if (ret!= ERRCODE_SLE_SUCCESS)
    {
        printf("%s sle add service fail, ret:%x\r\n", SLE_SERVER_LOG, ret);
        return ERRCODE_SLE_FAIL;
    }
  
    printf("%s sle add service out\r\n", SLE_SERVER_LOG);

    return ERRCODE_SLE_SUCCESS;
}

errcode_t sle_server_send_notify_by_handle(const uint8_t *data, uint8_t len)
{
   
    SsapsNtfInd param = {0};

   
    param.handle = g_property_handle;

  
    param.type = SSAP_PROPERTY_TYPE_VALUE;

   
    param.valueLen = len + 1; 

   
    param.value = osal_vmalloc(param.valueLen);
    if (param.value == NULL)
    {
        printf("[sle_server_send_notify_by_handle] osal_vmalloc fail\r\n");
        return ERRCODE_SLE_FAIL;
    }
   
    if (memcpy_s(param.value, param.valueLen, data, len)!= EOK)
    {
        osal_vfree(param.value);
        return ERRCODE_SLE_FAIL;
    }

   
    if (SsapsNotifyIndicate(g_server_id, g_sle_conn_id, &param)!= ERRCODE_SUCC)
    {
        printf("[sle_server_send_notify_by_handle] SsapsNotifyIndicate fail\r\n");
        osal_vfree(param.value);
        return ERRCODE_SLE_FAIL;
    }

    osal_vfree(param.value);
    return ERRCODE_SLE_SUCCESS;
}

static void sle_connect_state_changed_cbk(uint16_t conn_id, const SleAddr *addr,
                                          SleAcbStateType conn_state, SlePairStateType pair_state, SleDiscReasonType disc_reason)
{
    
    g_sle_conn_state = conn_state; 

    
    printf("%s [sle_connect_state_changed_cbk] conn_id:0x%02x, conn_state:0x%x, pair_state:0x%x, \
        disc_reason:0x%x\r\n",
                        SLE_SERVER_LOG, conn_id, conn_state, pair_state, disc_reason);
   
    printf("%s [sle_connect_state_changed_cbk] addr:%02x:%02x:%02x:%02x:%02x:%02x\r\n",
                        SLE_SERVER_LOG, addr->addr[0], addr->addr[1], addr->addr[2], addr->addr[3],
                        addr->addr[4], addr->addr[5]);

   
    if (conn_state == OH_SLE_ACB_STATE_CONNECTED)
    {
       
        g_sle_conn_id = conn_id;
    }

    
    else if (conn_state == OH_SLE_ACB_STATE_DISCONNECTED)
    {
       
        g_sle_conn_id = 0;
        g_sle_pair_state = OH_SLE_PAIR_NONE; 

    
        errcode_t ret = SleStartAnnounce(SLE_ADV_HANDLE_DEFAULT);
        if (ret!= ERRCODE_SLE_SUCCESS)
        {
            
            printf("%s [sle_connect_state_changed_cbk] sle_start_announce fail :%x\r\n", SLE_SERVER_LOG, ret);
        }
    }
}

static void sle_pair_complete_cbk(uint16_t conn_id, const SleAddr *addr, errcode_t status)
{
   
    printf("%s [sle_pair_complete_cbk] pair complete conn_id:%02x, status:%x\r\n", SLE_SERVER_LOG,
                        conn_id, status);
   
    printf("%s [sle_pair_complete_cbk] pair complete addr:%02x:%02x:%02x:%02x:%02x:%02x\r\n",
                        SLE_SERVER_LOG,
                        addr->addr[0], addr->addr[1], addr->addr[2],
                        addr->addr[3], addr->addr[4], addr->addr[5]);
    if (status == ERRCODE_SUCC)
    {
       
        g_sle_pair_state = OH_SLE_PAIR_PAIRED;
    }
}

static void sle_connect_param_update_req_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_req_t *param)
{
   
    printf("%s [sle_connect_param_update_req_cbk] conn_id:%02x, status:%x, interval_min:%02x, interval_max:%02x, max_latency:%02x, supervision_timeout:%02x\r\n",
                        SLE_SERVER_LOG, conn_id, status, param->interval_min, param->interval_max, param->max_latency, param->supervision_timeout);
}

static void sle_connect_param_update_cbk(uint16_t conn_id, errcode_t status, const SleConnectionParamUpdateEvt *param)
{
   
    printf("%s [sle_connect_param_update_cbk] conn_id:%02x, status:%x, interval:%02x, latency:%02x, supervision:%02x\r\n",
                        SLE_SERVER_LOG, conn_id, status, param->interval, param->latency, param->supervision);
}

static void sle_auth_complete_cbk(uint16_t conn_id, const SleAddr *addr, errcode_t status, const sle_auth_info_evt_t *evt)
{
    
    printf("%s [sle_auth_complete_cbk] auth complete conn_id:%02x, status:%x\r\n", SLE_SERVER_LOG,
                        conn_id, status);

    
    printf("%s [sle_auth_complete_cbk] auth complete addr:%02x:%02x:%02x:%02x:%02x:%02x\r\n",
                        SLE_SERVER_LOG, addr->addr[0], addr->addr[1], addr->addr[2], addr->addr[3],
                        addr->addr[4], addr->addr[5]);

   
    printf("%s [sle_auth_complete_cbk] auth complete link_key:%02x, crypto_algo:%x, key_deriv_algo:%x, integr_chk_ind:%x\r\n",
                        SLE_SERVER_LOG, evt->link_key, evt->crypto_algo, evt->key_deriv_algo, evt->integr_chk_ind);
}

static void sle_read_rssi_cbk(uint16_t conn_id, int8_t rssi, errcode_t status)
{
   
    printf("%s [sle_read_rssi_cbk] conn_id:%02x, rssi:%d, status:%x\r\n", SLE_SERVER_LOG,
                        conn_id, rssi, status);
}

static errcode_t sle_conn_register_cbks(void)
{
    errcode_t ret;
    SleConnectionCallbacks conn_cbks = {0};
    
    conn_cbks.connectStateChangedCb = sle_connect_state_changed_cbk;      
    
    conn_cbks.connectParamUpdateReqCb = sle_connect_param_update_req_cbk; 
   
    conn_cbks.connectParamUpdateCb = sle_connect_param_update_cbk;        
    
    conn_cbks.authCompleteCb = sle_auth_complete_cbk;                    
 
    conn_cbks.pairCompleteCb = sle_pair_complete_cbk;                    
   
    conn_cbks.readRssiCb = sle_read_rssi_cbk;                            

   
    ret = SleConnectionRegisterCallbacks(&conn_cbks); 
    if (ret!= ERRCODE_SLE_SUCCESS)
    {
       
        printf("%s [sle_conn_register_cbks] sle_connection_register_callbacks fail :%x\r\n",
                            SLE_SERVER_LOG, ret);
        return ret;
    }
    return ERRCODE_SLE_SUCCESS;
}

void ssaps_read_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_read_cb_t *read_cb_para,
                            errcode_t status)
{
    
    printf("[ssaps_read_request_cbk] server_id:0x%x, conn_id:0x%x, handle:0x%x, type:0x%x, status:0x%x\r\n",
           server_id, conn_id, read_cb_para->handle, read_cb_para->type, status);
}

void ssaps_write_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_write_cb_t *write_cb_para,
                             errcode_t status)
{
   
    (void)server_id;
    (void)conn_id;
    (void)status;

  
    
    uapi_watchdog_kick();

   
    if (write_cb_para->length > 0 && write_cb_para->value[0] == 'S' && write_cb_para->value[1] == 'E' && write_cb_para->value[2] == 'R' && write_cb_para->value[3] == 'V'
        && write_cb_para->value[4] == 'O' && write_cb_para->value[5] == '_' && write_cb_para->value[6] == 'M')
    {
       
        RegressMiddle();
    }

   
    if (write_cb_para->length > 0 && write_cb_para->value[0] == 'S' && write_cb_para->value[1] == 'E' && write_cb_para->value[2] == 'R' && write_cb_para->value[3] == 'V'
        && write_cb_para->value[4] == 'O' && write_cb_para->value[5] == '_' && write_cb_para->value[6] == 'L')
    {
       
        EngineTurnLeft();
    }

    if (write_cb_para->length > 0 && write_cb_para->value[0] == 'S' && write_cb_para->value[1] == 'E' && write_cb_para->value[2] == 'R' && write_cb_para->value[3] == 'V'
        && write_cb_para->value[4] == 'O' && write_cb_para->value[5] == '_' && write_cb_para->value[6] == 'R')
    {
       
        EngineTurnRight();
    }

    
    write_cb_para->value[write_cb_para->length - 1] = '\0';
    
    printf("[ssaps_write_request_cbk] client_send_data: %s\r\n", write_cb_para->value);

    
    char *data = "Response from SLE server!\n";
   
    int ret = sle_server_send_data((uint8_t *)data, strlen(data));
}

errcode_t sle_server_init()
{
    errcode_t ret;

   
    ret = sle_announce_register_cbks();
    if (ret!= ERRCODE_SLE_SUCCESS)
    {
       
        printf("%s [sle_server_init] sle_announce_register_cbks fail :%x\r\n",
                            SLE_SERVER_LOG, ret);
        return ret;
    }

    
    ret = sle_conn_register_cbks();
    if (ret!= ERRCODE_SLE_SUCCESS)
    {
        printf("%s [sle_server_init] sle_conn_register_cbks fail :%x\r\n", SLE_SERVER_LOG, ret);
        return ret;
    }

    
    ret = sle_ssaps_register_cbks(ssaps_read_request_cbk, ssaps_write_request_cbk);
    if (ret!= ERRCODE_SLE_SUCCESS)
    {
        printf("%s [sle_server_init] sle_ssaps_register_cbks fail :%x\r\n", SLE_SERVER_LOG, ret);
        return ret;
    }

   
    ret = EnableSle();
    if (ret!= ERRCODE_SLE_SUCCESS)
    {
        printf("%s [sle_server_init] enable_sle fail :%x\r\n", SLE_SERVER_LOG, ret);
        return ret;
    }

   
    printf("%s [sle_server_init] init ok\r\n", SLE_SERVER_LOG);
    return ERRCODE_SLE_SUCCESS;
}

errcode_t sle_enable_server_cbk(void)
{
    errcode_t ret;

    
    ret = sle_server_add();
    if (ret!= ERRCODE_SLE_SUCCESS)
    {
        printf("%s [sle_enable_cbk] sle_server_add fail :%x\r\n", SLE_SERVER_LOG, ret);
        return ret;
    }

   
    ret = sle_server_adv_init();
    if (ret!= ERRCODE_SLE_SUCCESS)
    {
        printf("%s [sle_enable_cbk] sle_server_adv_init fail :%x\r\n", SLE_SERVER_LOG, ret);
        return ret;
    }

    return ERRCODE_SLE_SUCCESS;
}

int sle_server_send_data(uint8_t *data, uint8_t length)
{
    int ret;
  
    ret = sle_server_send_notify_by_handle(data, length);
    return ret;
}

void sle_wait_client_paired(void)
{
  
    while (g_sle_pair_state!= OH_SLE_PAIR_PAIRED)
    {
       
        osal_msleep(100); 
    }
}

void sle_wait_client_connected(void)
{
  
    while (g_sle_conn_state!= OH_SLE_ACB_STATE_CONNECTED)
    {
        
        osal_msleep(100); 
    }
}
